package DEEPERsource.DEEPERsource.source.machinelearning.utils;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import deeper.Interaction;

import machinelearning.wekawrapper.Dataset;
import net.sf.javaml.classification.evaluation.PerformanceMeasure;

public class ClassificationResult {
	
	public double treshold = 0.5;
	
	/*public Map<Interaction, Integer> getClassificationFile4SVM(String file, Dataset data, int negativeClassValue, int... positiveClassValues){
		Map<Interaction, Integer> result = new HashMap<Interaction, Integer>();
		try {
			BufferedReader in = new BufferedReader(new FileReader(file));
			String s = in.readLine();
			String[] labels = s.split("\\s");
			int[] map = new int[labels.length-1];
			for (int k = 1; k < labels.length; k++)
				map[k-1] = Integer.parseInt(labels[k]);
			int inst = 0;
			while ((s = in.readLine()) != null) {
				Interaction id = data.getInteractions().get(inst++);
				String[] parse = s.split("\\s");
				double[] dist = new double[labels.length - 1];
				for (int k = 1; k < labels.length; k++)
					dist[k - 1] = Double.parseDouble(parse[k]);
				double sum = 0;
				int predClass = 0;
				double maxVal = 0;
				for(int i = 0; i<dist.length; i++ ){
					if(map[i] != negativeClassValue){
						sum += dist[i];
						if(maxVal<dist[i]){
							maxVal = dist[i];
							predClass = map[i];
						}
					}
				}				
				if(sum>=treshold){
					result.put(id, predClass);
				}else{
					result.put(id, negativeClassValue);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}*/
	
	// List entry contains following fields:
	// probability-to-be-positive	predictedClass	realClass
	public List<String> getClassification4SVM(String file, List<String> classValues, 
			int negativeClassValue, int... positiveClassValues){
		List<String> list = new ArrayList<String>();
		try {
			BufferedReader in = new BufferedReader(new FileReader(file));
			String s = in.readLine();
			String[] labels = s.split("\\s");
			int[] map = new int[labels.length-1];
			for (int k = 1; k < labels.length; k++)
				map[k-1] = Integer.parseInt(labels[k]);
			int i = 0;
			while ((s = in.readLine()) != null) {
				String[] parse = s.split("\\s");
				double[] dist = new double[labels.length - 1];
				for (int k = 1; k < labels.length; k++)
					dist[k - 1] = Double.parseDouble(parse[k]);
				double sum = 0;
				int predClass = 0;
				double maxVal = 0;
				for(int k = 0; k<dist.length; k++ ){
					if(map[k] != negativeClassValue){
						sum += dist[k];
						if(maxVal<dist[k]){
							maxVal = dist[k];
							predClass = map[k];
						}
					}
				}
				if(sum<treshold)
					predClass = negativeClassValue;
				list.add(Double.toString(sum)+"\t"+Integer.toString(predClass)+"\t"+classValues.get(i));
				i++;
			}			
		} catch (IOException e) {
			e.printStackTrace();
		}
		return list;
	}

	public PerformanceMeasure getPerformance4SVM(List<String> realClassList, List<String> predClassList, int negativeClassValue) {
		PerformanceMeasure pm = new PerformanceMeasure();
		for(int i = 0, size = realClassList.size(); i< size; i++){
			int real = Integer.parseInt(realClassList.get(i));
			int pred = Integer.parseInt(predClassList.get(i).split("\t")[1]);
			if(real == negativeClassValue){
				if(real == pred)
					pm.trueNegatives++;
				else
					pm.falsePositives++;
			}else{
				if(real == pred)
					pm.truePositives++;
				else
					if(pred==negativeClassValue)
						pm.falseNegatives++;
					else
						pm.falsePositives++;
			}
		}
		
		/*try {
			BufferedReader in = new BufferedReader(new FileReader(file));
			String s = in.readLine();
			String[] labels = s.split("\\s");
			int[] map = new int[labels.length-1];
			for (int k = 1; k < labels.length; k++)
				map[k-1] = Integer.parseInt(labels[k]);

			int ind = 0;
			while ((s = in.readLine()) != null) {
				String[] parse = s.split("\\s");
				//int realClass = Integer.parseInt(parse[0]);
				int realClass = Integer.parseInt(realClassList.get(ind));
				double[] dist = new double[labels.length - 1];
				for (int k = 1; k < labels.length; k++)
					dist[k - 1] = Double.parseDouble(parse[k]);
				double sum = 0;
				int predClass = 0;
				double maxVal = 0;
				for(int i = 0; i<dist.length; i++ ){
					if(map[i] != negativeClassValue){
						sum += dist[i];
						if(maxVal<dist[i]){
							maxVal = dist[i];
							predClass = map[i];
						}
					}
				}
				//check if probability of positive classification above treshold
				if(sum>=treshold){
					//and if yes, accepting that the class is classified positively
					//and check, if the positive class chosen properly
					if(predClass==realClass)
						pm.truePositives++;
					else
						//if the instance misclassified
						//(i.e. it is a negative instance, or positive class wasn't guessed)
						pm.falsePositives++;
				}else{
					//if the instance is predicted to be negative
					if(realClass==negativeClassValue)
						pm.trueNegatives++;
					else
						pm.falseNegatives++;
				}
				ind++;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}*/
		return pm;
	}
}
